package com.moli.iov.base.remote.impl;

import com.alibaba.fastjson.JSON;
import com.moli.iov.base.enums.FenceAlarmTypeEnum;
import com.moli.iov.base.enums.FenceShapeEnum;
import com.moli.iov.base.enums.QueryParamEnum;
import com.moli.iov.base.enums.YesOrNoEnum;
import com.moli.iov.base.model.VehicleFenceParam;
import com.moli.iov.base.model.dto.req.QueryVehicleFenceOpDto;
import com.moli.iov.base.model.dto.req.VehicleFenceReqDto;
import com.moli.iov.base.model.dto.req.VehicleFenceReqOpDto;
import com.moli.iov.base.model.dto.res.VehicleFenceGpsResDto;
import com.moli.iov.base.model.dto.res.VehicleFenceInfoResOpDto;
import com.moli.iov.base.model.dto.res.VehicleFenceResDto;
import com.moli.iov.base.model.dto.res.VehicleFenceResOpDto;
import com.moli.iov.base.model.po.VehicleFence;
import com.moli.iov.base.model.po.VehicleFenceBinding;
import com.moli.iov.base.remote.IVehicleFenceRemoteService;
import com.moli.iov.base.service.IVehicleFenceBindingService;
import com.moli.iov.base.service.IVehicleFenceService;
import com.moli.iov.base.util.CollectionUtils;
import com.moli.iov.enums.UserTypeEnum;
import com.moli.iov.model.Location;
import com.moli.iov.model.dto.req.PageExtend;
import com.moli.iov.rest.RestResponse;
import com.moli.iov.util.CommonUtils;
import com.moli.iov.util.GeoUtils;
import com.moli.iov.util.JsonUtils;
import com.moli.iov.util.StringUtil;
import com.moli.iov.util.ValidationUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

/**
 * 围栏业务处理
 *
 * @author whl
 * @date 2019-09-20 20:10:44
 */
@Slf4j
@Service(group = "${service.group}")
@Transactional(rollbackFor = Exception.class)
public class IVehicleFenceRemoteServiceImpl implements IVehicleFenceRemoteService {

  @Autowired
  private IVehicleFenceService iVehicleFenceService;
  @Autowired
  private IVehicleFenceBindingService bindingService;

  @Override
  public RestResponse saveVehicleFence(VehicleFenceReqDto dto) {
    log.info("车辆监控-电子围栏-添加-入参:{}" + JsonUtils.toJson(dto));
    ValidationUtils.validateBean(dto, VehicleFenceReqDto.Save.class);
    Date now = Calendar.getInstance().getTime();
    dto.setGmtCreate(now);
    dto.setGmtModified(now);
    dto.setCreateUser(dto.getSysUserId().toString());
    dto.setModifiedUser(dto.getSysUserId().toString());
    VehicleFence vehicleFence = new VehicleFence();
    CommonUtils.copyProperties(dto, vehicleFence);
    vehicleFence.setFenceAreaCoordinate(JsonUtils.toJson(dto.getFenceAreaCoordinate()));
    vehicleFence.setFenceAreaCoordinateRange(JsonUtils.toJson(dto.getFenceAreaCoordinateRange()));
    RestResponse restResponse = iVehicleFenceService.saveVehicleFence(vehicleFence);
    log.info("车辆监控-电子围栏-添加-出参:{}",JsonUtils.toJson(restResponse));
    return restResponse;
  }

  @Override
  public RestResponse updateVehicleFence(VehicleFenceReqDto dto) {
    log.info("车辆监控 - 电子围栏-更新入参{}：" + dto);
    ValidationUtils.validateBean(dto, VehicleFenceReqDto.Update.class);
    VehicleFence vehicleFence = iVehicleFenceService.getVehicleFence(dto.getId());
    if (vehicleFence == null) {
      return RestResponse.failure("围栏不存在");
    }
    //企业用户只能修改自己企业的围栏
    if (dto.getSysUserType().intValue() == UserTypeEnum.COMPANY.getFlag()
        && dto.getSysCompanyId().longValue() != vehicleFence.getCompanyId().longValue()) {
      return RestResponse.failure("修改围栏失败");
    }
    Date now = Calendar.getInstance().getTime();
    dto.setGmtModified(now);
    dto.setModifiedUser(dto.getSysUserId().toString());
    CommonUtils.copyProperties(dto, vehicleFence);
    vehicleFence.setFenceAreaCoordinate(JsonUtils.toJson(dto.getFenceAreaCoordinate()));
    vehicleFence.setFenceAreaCoordinateRange(JsonUtils.toJson(dto.getFenceAreaCoordinateRange()));
    return iVehicleFenceService.updateVehicleFence(vehicleFence);
  }

  @Override
  public RestResponse deleteVehicleFence(VehicleFenceReqDto dto) {
    log.info("车辆监控-电子围栏-删除-入参{}：",JsonUtils.toJson(dto) );
    ValidationUtils.validateBean(dto, VehicleFenceReqDto.Delete.class);
    VehicleFence vehicleFence = iVehicleFenceService.getVehicleFence(dto.getId());
    ValidationUtils.validateBean(vehicleFence);
    //企业用户只能删除自己企业的围栏
    if (dto.getSysUserType().intValue() == UserTypeEnum.COMPANY.getFlag()
        && dto.getSysCompanyId().longValue() != vehicleFence.getCompanyId().longValue()) {
      return RestResponse.failure("删除围栏失败");
    }
    List<VehicleFenceBinding> list = bindingService
        .listVehicleFenceBinding(vehicleFence.getId(), null);
    if (!CollectionUtils.isEmpty(list)) {
      return RestResponse.failure("此围栏绑定有车辆，请先解绑车辆后重试。");
    }
    vehicleFence.setGmtModified(Calendar.getInstance().getTime());
    vehicleFence.setCreateUser(dto.getSysUserId().toString());
    vehicleFence.setIsDelete(YesOrNoEnum.YES.getCode());
    RestResponse restResponse = iVehicleFenceService.deleteVehicleFence(vehicleFence);
    log.info("车辆监控-电子围栏-删除-出参{}：",JsonUtils.toJson(restResponse) );
    return restResponse;
  }

  @Override
  public RestResponse<PageExtend<VehicleFenceResDto>> listVehicleFence(VehicleFenceReqDto dto) {
    log.info("车辆监控 - 电子围栏-列表-入参:{}", dto);
    ValidationUtils.validateBean(dto);
    //围栏绑定   查询参数（0：车牌号，1：vin 2, 围栏名称 3 围栏区域）
    if (Objects.equals(dto.getQueryParam(), QueryParamEnum.VIN.getCode())&& StringUtil.isNotBlank(dto.getQueryValue())){
         return listFenceByVin(dto);
    }else{
    RestResponse<PageExtend<VehicleFenceResDto>> page = iVehicleFenceService
        .listVehicleFence(dto);
    return page;
  }
  }

  /**
   * 根据vin查找绑定的围栏
   *
   * @param dto the dto
   * @return the rest response
   * @author wanghualin
   */
  public RestResponse<PageExtend<VehicleFenceResDto>> listFenceByVin(VehicleFenceReqDto dto){
    List<VehicleFence> vehicleFences = bindingService.listFenceIdByVin(dto.getQueryValue());
    List<VehicleFenceResDto> list = new ArrayList<>();
    PageExtend<VehicleFenceResDto> res = new PageExtend<>();
    if (!CollectionUtils.isEmpty(vehicleFences)) {
      for (VehicleFence record : vehicleFences) {
        VehicleFenceResDto vehicleFenceResDto = new VehicleFenceResDto();
        CommonUtils.copyProperties(record, vehicleFenceResDto);
        vehicleFenceResDto
                .setFenceAreaCoordinateList(JsonUtils.parse(record.getFenceAreaCoordinate(),
                        VehicleFenceGpsResDto.class));
        vehicleFenceResDto
                .setFenceAreaCoordinateRangeList(JSON.parseArray(record.getFenceAreaCoordinateRange(),
                        VehicleFenceGpsResDto.class));
        //企业用户只能查看自己绑定的
        if (dto.getSysUserType().intValue() == UserTypeEnum.COMPANY.getFlag()
        ) {
          if (dto.getSysCompanyId().longValue() == vehicleFenceResDto.getCompanyId().longValue()){
            list.add(vehicleFenceResDto);
          }
        }else{
          list.add(vehicleFenceResDto);
        }
      }
      res.setRecords(list);
    }
    res.setPageSize(dto.getPageSize());
    res.setTotal((long) list.size());
    res.setPageNumber(dto.getPageNum());
    return RestResponse.success(res);
  }

  @Override
  public RestResponse redrawVehicleFence(VehicleFenceReqDto dto) {
    log.info("车辆监控 - 电子围栏-重绘入参{}：" + dto);
    ValidationUtils.validateBean(dto, VehicleFenceReqDto.Redraw.class);
    VehicleFence vehicleFence = iVehicleFenceService.getVehicleFence(dto.getId());
    if (vehicleFence == null) {
      return RestResponse.failure("围栏不存在");
    }
    //企业用户只能修改自己企业的围栏
    if (dto.getSysUserType().intValue() == UserTypeEnum.COMPANY.getFlag()
        && dto.getSysCompanyId().longValue() != vehicleFence.getCompanyId().longValue()) {
      return RestResponse.failure("重绘围栏失败");
    }
    Date now = Calendar.getInstance().getTime();
    dto.setGmtModified(now);
    dto.setModifiedUser(dto.getSysUserId().toString());
    CommonUtils.copyProperties(dto, vehicleFence);
    vehicleFence.setFenceAreaCoordinate(JsonUtils.toJson(dto.getFenceAreaCoordinate()));
    vehicleFence.setFenceAreaCoordinateRange(JsonUtils.toJson(dto.getFenceAreaCoordinateRange()));
    return iVehicleFenceService.updateVehicleFence(vehicleFence);
  }

  @Override
  public RestResponse saveVehicleFenceOp(VehicleFenceReqOpDto dto) {
    log.info("op-车辆监控 - 电子围栏-添加 入参{}：" + dto);
    ValidationUtils.validateBean(dto, VehicleFenceReqOpDto.Save.class);
    List<Location> locations = null;
    if (dto.getFenceShape().intValue() == FenceShapeEnum.SQUARE.getCode()) {
      locations = GeoUtils
          .returnLLSquarePointList(dto.getFenceAreaCoordinate().getLongitude(),
              dto.getFenceAreaCoordinate().getLatitude(), dto.getRadius());
    }
    Date now = Calendar.getInstance().getTime();
    VehicleFence vehicleFence = new VehicleFence();
    CommonUtils.copyProperties(dto, vehicleFence);
    //设置来源op
    vehicleFence.setSource(1);
    vehicleFence.setFenceAreaCoordinate(JsonUtils.toJson(dto.getFenceAreaCoordinate()));
    vehicleFence.setFenceAreaCoordinateRange(JsonUtils.toJson(locations));
    vehicleFence.setGmtCreate(now);
    vehicleFence.setGmtModified(now);
    vehicleFence.setCompanyId(dto.getCompanyId());
    vehicleFence.setCompanyName(dto.getCompanyName());
    return iVehicleFenceService.saveVehicleFence(vehicleFence);
  }

  @Override
  public RestResponse updateVehicleFenceOp(VehicleFenceReqOpDto dto) {
    log.info("op-车辆监控 - 电子围栏-更新 入参{}：" + dto);
    VehicleFence vehicleFence = iVehicleFenceService.getVehicleFence(dto.getId());
    if (vehicleFence == null) {
      return RestResponse.failure("围栏不存在");
    }
    //企业用户只能修改自己企业的围栏
    if (dto.getCompanyId().longValue() != vehicleFence.getCompanyId().longValue()) {
      return RestResponse.failure("修改围栏失败");
    }
    Date now = Calendar.getInstance().getTime();

    CommonUtils.copyProperties(dto, vehicleFence);
    List<Location> locations = null;
    if (dto.getFenceShape().intValue() == FenceShapeEnum.SQUARE.getCode()) {
      locations = GeoUtils
          .returnLLSquarePointList(dto.getFenceAreaCoordinate().getLongitude(),
              dto.getFenceAreaCoordinate().getLatitude(), dto.getRadius());
    }

    vehicleFence.setGmtModified(now);
    vehicleFence.setFenceAreaCoordinate(JsonUtils.toJson(dto.getFenceAreaCoordinate()));
    vehicleFence.setFenceAreaCoordinateRange(JsonUtils.toJson(locations));
    return iVehicleFenceService.updateVehicleFence(vehicleFence);
  }

  @Override
  public RestResponse deleteVehicleFenceOp(VehicleFenceReqOpDto dto) {
    log.info("op-车辆监控 - 电子围栏-删除 入参{}：" + dto);
    ValidationUtils.validateBean(dto, VehicleFenceReqDto.Delete.class);
    VehicleFence vehicleFence = iVehicleFenceService.getVehicleFence(dto.getId());
    ValidationUtils.validateBean(vehicleFence);
    //企业用户只能删除自己企业的围栏
    if (dto.getCompanyId().longValue() != vehicleFence.getCompanyId().longValue()) {
      return RestResponse.failure("删除围栏失败");
    }
    List<VehicleFenceBinding> list = bindingService
        .listVehicleFenceBinding(vehicleFence.getId(), null);
    if (!CollectionUtils.isEmpty(list)) {
      return RestResponse.failure("此围栏绑定有车辆，请先解绑车辆后重试。");
    }
    vehicleFence.setGmtModified(Calendar.getInstance().getTime());
    vehicleFence.setIsDelete(YesOrNoEnum.YES.getCode());
    return iVehicleFenceService.deleteVehicleFence(vehicleFence);
  }

  @Override
  public List<VehicleFence> listVehicleFenceByVin(String vin) {
    return bindingService.listFenceIdByVin(vin);
  }

  @Override
  public RestResponse VehicleFenceById(Long fenceId) {
    VehicleFence vehicleFence = iVehicleFenceService.getVehicleFence(fenceId);
    return RestResponse.success(vehicleFence);
  }

  /**
   * op 查询所有围栏
   * fenceIdList 可以为null,为null时。查找全部
   *
   * @param dto the dto
   * @return rest response
   * @author wanghualin
   */
  @Override
  public RestResponse listVehicleFenceOp(QueryVehicleFenceOpDto dto) {
    log.info("op查询所有围栏接口:{}", dto);
    ValidationUtils.validateBean(dto);
    List<VehicleFence> vehicleFenceList=null;
    if (dto.getFenceIdList()==null||CollectionUtils.isEmpty(dto.getFenceIdList())){
      vehicleFenceList = iVehicleFenceService.listVehicleFence();
    if (vehicleFenceList==null||vehicleFenceList.isEmpty()){
      return RestResponse.success(); }
    }else{
       vehicleFenceList = iVehicleFenceService.listVehicleFenceByOpIds(dto.getFenceIdList(),dto.getCompanyId());
      if (vehicleFenceList==null||vehicleFenceList.isEmpty()){
        return RestResponse.success();
      }
    }
    //只要茉莉
    List<VehicleFence> collect = vehicleFenceList.stream().filter(vehicleFence -> vehicleFence.getCompanyId().longValue()
            == dto.getCompanyId().longValue()&&vehicleFence.getAlarmType().intValue()== FenceAlarmTypeEnum.OUT.getCode())
            .collect(Collectors.toList());
    List<VehicleFenceResOpDto> list = new ArrayList<>();
    if (!CollectionUtils.isEmpty(collect)) {
      for (VehicleFence record : collect) {
        VehicleFenceResOpDto vehicleFenceResDto = new VehicleFenceResOpDto();
        CommonUtils.copyProperties(record, vehicleFenceResDto);
        vehicleFenceResDto
                .setFenceAreaCoordinateList(JsonUtils.parse(record.getFenceAreaCoordinate(),
                        VehicleFenceGpsResDto.class));
        vehicleFenceResDto
                .setFenceAreaCoordinateRangeList(JSON.parseArray(record.getFenceAreaCoordinateRange(),
                        VehicleFenceGpsResDto.class));
        list.add(vehicleFenceResDto);
      }
    }
    return RestResponse.success(list);
  }

  /**
   * 围栏是否绑定有车  fenceId
   * @param dto
   * @return
   */
  @Override
  public RestResponse isBindingVehicleByFenceId(QueryVehicleFenceOpDto dto) {
    log.info("op-车辆监控 - 电子围栏-添加 入参{}：" + dto);
    ValidationUtils.validateBean(dto);
    VehicleFence vehicleFence = iVehicleFenceService.getVehicleFence(dto.getFenceId());
    if (vehicleFence!=null&&dto.getCompanyId().longValue()==vehicleFence.getCompanyId().longValue()){
      int i = bindingService.countVehicleFenceBinding(dto.getFenceId());
      return RestResponse.success(i>0);
    }else{
      return RestResponse.failure("围栏不存在");
    }
  }

  @Override
  public RestResponse listVehicleFenceByFenceNameOp(QueryVehicleFenceOpDto dto) {
    log.info("根据围栏名称模糊查找围栏入参:{}", dto);
    ValidationUtils.validateBean(dto);
    List<VehicleFenceInfoResOpDto> res=new ArrayList<>();
    VehicleFenceParam param = new VehicleFenceParam();
    param.queryEqCompanyId(dto.getCompanyId());
    param.queryLikeFenceName(dto.getFenceName());
    param.queryEqAlarmType(FenceAlarmTypeEnum.OUT.getCode());
    List<VehicleFence> list = iVehicleFenceService.list(param.get());
    if (!CollectionUtils.isEmpty(list)) {
      for (VehicleFence record : list) {
        VehicleFenceInfoResOpDto vehicleFenceResDto = new VehicleFenceInfoResOpDto();
        CommonUtils.copyProperties(record, vehicleFenceResDto);
        res.add(vehicleFenceResDto);
      }
    }
    return RestResponse.success(res);
  }

  /**
   * 根据vinList返回围栏信息
   *
   * @param dto the dto
   * @return the rest response
   * @author wanghualin
   */
  @Override
  public RestResponse listVehicleFenceByVinList(QueryVehicleFenceOpDto dto) {
    ValidationUtils.validateBean(dto);
    log.info("op:根据车架号返回围栏信息入参:{}", dto);
    List<VehicleFenceBinding> list = bindingService.listVehicleFenceBinding(dto.getVinList());
    if (list==null||list.isEmpty()){
      RestResponse.success();
    }
    Set<Long> collect1 = list.stream().collect(Collectors.mapping(VehicleFenceBinding::getFenceId, Collectors.toSet()));
    List<VehicleFence> vehicleFences = iVehicleFenceService.listVehicleFenceByIds(collect1);
    if (vehicleFences==null||vehicleFences.isEmpty()){
      RestResponse.success();
    }
    Map<Long, VehicleFence> vehicleFenceMap = vehicleFences.stream().
            filter(vehicleFence -> vehicleFence.getCompanyId().longValue() == dto.getCompanyId()
                    &&vehicleFence.getAlarmType().intValue()==FenceAlarmTypeEnum.OUT.getCode()).
            collect(Collectors.toMap(VehicleFence::getId, vehicleFence -> vehicleFence));
    Map<String, List<Long>> collect = list.stream().
            collect(Collectors.groupingBy(VehicleFenceBinding::getVin,
                    Collectors.mapping(VehicleFenceBinding::getFenceId,
                            Collectors.toList())));
    Map<String,List<VehicleFenceInfoResOpDto>>res=new HashMap<>();
    collect.forEach((s, longs) -> {
         if (!longs.isEmpty()){
           List<VehicleFenceInfoResOpDto> opResDtoList=new ArrayList<>();
           for (Long aLong : longs) {
             VehicleFenceInfoResOpDto vehicleFenceOpResDto=new VehicleFenceInfoResOpDto();
             VehicleFence vehicleFence = vehicleFenceMap.get(aLong);
             if (vehicleFence!=null){
                CommonUtils.copyProperties(vehicleFence,vehicleFenceOpResDto);
                opResDtoList.add(vehicleFenceOpResDto);
             }
           }
            if (opResDtoList.size()>0){
              res.put(s,opResDtoList);
            }
         }
    });
    return RestResponse.success(res);
  }

  @Override
  public RestResponse getVehicleFenceOpById(Long fenceId) {
    VehicleFence vehicleFence = iVehicleFenceService.getVehicleFence(fenceId);
    if (vehicleFence==null){
      return  RestResponse.success();
    }else{
      VehicleFenceInfoResOpDto dto=new VehicleFenceInfoResOpDto();
       CommonUtils.copyProperties(vehicleFence,dto);
      return RestResponse.success(dto);
    }
  }
}
